/**
 * futures : masterlink.futures.dao.GroupDao.java
 */
package masterlink.futures.dao;

import java.util.ArrayList;
import java.util.List;

import masterlink.futures.vo.Account;
import masterlink.futures.vo.FutmatDetail;
import masterlink.futures.vo.FutpabReal;
import masterlink.futures.vo.FutpabRealSum;
import masterlink.futures.vo.Group;
import masterlink.futures.vo.RealReposotory;
import masterlink.futures.vo.RepositoryGreeksG;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;

import baytony.util.Util;

/**
 * TODO Write the description
 *
 * @author : tonyyang
 * Create date : 2011/10/25
 * @version 1.0.0	
 */
@Repository
@Qualifier("RealRepositoryDao")
public class RealRepositoryDao extends TimesTenTemplateDao{
	
	//private static final String FIND_BY_GROUP="select {b.*},{c.*} from greeks_limit a,fuminv b, futpabreal c where a.account=b.acno and a.broker=b.broker_id and a.account=c.acno(+) and a.broker=c.broker_id(+) and a.id=?";
	private static final String FIND_BY_GROUP="select c.trid, c.buysell, sum(quantity) as quantity, (sum(avgprice)/sum(quantity)) as avgprice, c.tag1 "+
												"from greeks_limit a,fuminv b, futpabreal c "+
												"where a.account=b.acno and a.broker=b.broker_id "+ 
												"and a.account=c.acno and a.broker=c.broker_id "+
												"and a.id=? "+
												"group by c.trid, c.buysell, c.tag1 "+ 
												"order by c.trid, c.tag1 ";
	private static final String FIND_BY_ACC="select {b.*},{c.*} from greeks_limit a,fuminv b, futpabreal c " +
												"where a.account=b.acno and a.broker=b.broker_id " +
												"and a.account=c.acno(+) and a.broker=c.broker_id(+) " +
												"and a.id=? and a.account=? ";
	private static final String FIND_BY_ACC2="select {b.*},{c.*} from greeks_limit a,fuminv b, futmatdetailView2 c " +
			"where a.account=b.acno and a.broker=b.broker_id " +
			"and a.account=c.acno(+) and a.broker=c.broker_id(+) " +
			"and a.id=? and a.account=? and tag2=?";
	private static final String FIND_BY_TRID="select {b.*},{c.*} from greeks_limit a,fuminv b, futpabreal c " +
												"where a.account=b.acno and a.broker=b.broker_id " +
												"and a.account=c.acno and a.broker=c.broker_id " +
												"and a.id=? "+
												"and c.trid=? and c.buysell=? and "+
												"order by b.acno ";
	private static final String FIND_BY_TRID1="select {b.*},{c.*} from greeks_limit a,fuminv b, futpabreal c " +
			"where a.account=b.acno and a.broker=b.broker_id " +
			"and a.account=c.acno and a.broker=c.broker_id " +
			"and a.id=? "+
			"and c.trid=? "+
			"order by b.acno ";
	public List<FutpabRealSum> findByGroup(Group group) {
		if(group!=null){
			return (List<FutpabRealSum>) findBySql(FIND_BY_GROUP,FutpabRealSum.class, group.getId());
		}
		return null;
	}
	
	public List<FutpabRealSum> findByGroup1(Group group) {
		if(group!=null){
			return createSum(findBySql(FIND_BY_GROUP,FutpabRealSum.class, group.getId()));
		}
		return null;
	}
	
	public List<FutpabRealSum> createSum(List<FutpabRealSum> all) {
		List<FutpabRealSum> res=new ArrayList<FutpabRealSum>();
		if(!Util.isEmptyList(all)){
			for(int i=0;i<all.size();i++){
				FutpabRealSum r=new FutpabRealSum();
				if(i+1>=all.size()){
					r.setId(all.get(i).getId());
					r.setQuantity(all.get(i).getQuantity());
					r.setAvgPrice(all.get(i).getAvgPrice());
					res.add(r);
					break;
				}
				if(all.get(i).getId().getTrid().equals(all.get(i+1).getId().getTrid())){
					if(all.get(i).getQuantity() == all.get(i+1).getQuantity()){
						i++;
						continue;
					}
					double price1;
					if(all.get(i).getQuantity()>all.get(i+1).getQuantity()){
						r.setId(all.get(i).getId());
						r.setQuantity(all.get(i).getQuantity() + all.get(i+1).getQuantity());
						r.setAvgPrice(all.get(i).getAvgPrice());
					}else{
						r.setId(all.get(i+1).getId());
						r.setQuantity(all.get(i+1).getQuantity() + all.get(i).getQuantity());
						r.setAvgPrice(all.get(i+1).getAvgPrice());
					}
					i++;
				}else{
					r.setId(all.get(i).getId());
					r.setQuantity(all.get(i).getQuantity());
					r.setAvgPrice(all.get(i).getAvgPrice());
				}
				res.add(r);
			}
		}
		return res;
	}
	
	@SuppressWarnings("unchecked")
	public List<RealReposotory> findByAccount(Group group,Account acc) {
		if(group!=null&&acc!=null){
			return create((List<Object[]>) executeQuery(createSqllQuery(FIND_BY_ACC).
					addEntity("b",Account.class).addEntity("c",FutpabReal.class), group.getId(),acc.getId().getAcno()));
		}
		return null;
	}
	@SuppressWarnings("unchecked")
	public List<RealReposotory> findByAccount2(Group group,Account acc) {
		if(group!=null&&acc!=null){
			return create2((List<Object[]>) executeQuery(createSqllQuery(FIND_BY_ACC2).
					addEntity("b",Account.class).addEntity("c",FutmatDetail.class), group.getId(),acc.getId().getAcno(),2));
		}
		return null;
	}
	
	@SuppressWarnings("unchecked")
	public List<RealReposotory> findByTrid(Group group,String trid,String buysell) {
		if(trid!=null&&buysell!=null){
			return create((List<Object[]>) executeQuery(createSqllQuery(FIND_BY_TRID).
					addEntity("b",Account.class).addEntity("c",FutpabReal.class), group.getId(),trid,buysell));
		}
		return null;
	}
	@SuppressWarnings("unchecked")
	public List<RealReposotory> findByTrid1(Group group,String trid,String buysell) {
		if(trid!=null&&buysell!=null){
			return create((List<Object[]>) executeQuery(createSqllQuery(FIND_BY_TRID1).
					addEntity("b",Account.class).addEntity("c",FutpabReal.class), group.getId(),trid));
		}
		return null;
	}
	
	private List<RealReposotory> create(List<Object[]> all){
		List<RealReposotory> res=new ArrayList<RealReposotory>();
		if(!Util.isEmptyList(all)){
			for(Object[] o:all){
				RealReposotory e=new RealReposotory((Account)o[0]);
				if(!res.contains(e)){
					e.addFutpabReal((FutpabReal)o[1]);
					res.add(e);
				}else{
					res.get(res.indexOf(e)).addFutpabReal((FutpabReal)o[1]);
				}
			}
		}
		log.trace("{} of Equity was found.",res.size());
		return res;
	}
	private List<RealReposotory> create2(List<Object[]> all){
		List<RealReposotory> res=new ArrayList<RealReposotory>();
		if(!Util.isEmptyList(all)){
			for(Object[] o:all){
				RealReposotory e=new RealReposotory((Account)o[0]);
				if(!res.contains(e)){
					e.addFutmatDetail((FutmatDetail)o[1]);
					res.add(e);
				}else{
					res.get(res.indexOf(e)).addFutmatDetail((FutmatDetail)o[1]);
				}
			}
		}
		log.trace("{} of Equity was found.",res.size());
		return res;
	}
}
